home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
-
- Copyright 1990,1991 Orion Network Systems, Inc.
- All Rights reserved.
-
- File: TracksDCMD.c
- Author: Brad Lowe
-
- Tracks Debugger Command tool... Allows you to do rudimentary Tracks
- functions from the debugger. This should only be used if your machine
- crashes, and you have data in the circular buffer you want sent to a file.
- Of couse there is no gaurentee that the Tracks driver is not trashed, and if
- it is, the debugger will lockup.. Use this when you are sure there
- is no more information to be gained from poking around in the debugger.
-
- Commands supported are:
- On: Turns tracing on. You must specify the target driver (the one
- you are tracing, by doing a Tracks On .TestDrvr or whatever.
-
- ** The buffer must be initialized through the cdev before this call will work!
-
- Off: Turns tracing off.
- Write: Writes whatever is in the buffer to your prefrence file.
- Info: Displays some info about Tracks.
-
- Remember that the cdev must be initialized once before you can use this...
- It can be started from startup or from the cdev...
-
- Building:
-
- The following MPW commands will build the dcmd and copy it to the
- "Debugger Prefs" file in the System folder. The dcmd's name in
- MacsBug will be the name of the file built by the Linker.
-
- ** This file must be in a folder within the Tracks source code folder.
-
- Note: Be sure to link dcmdGlue.a.o first. The files in the
- dcmd libraries folder should come with Macsbugs
-
- C TracksDCMD.c
- Link "{dcmdLib}"dcmdGlue.a.o TracksDCMD.c.o "{dcmdLib}"put.c.o ∂
- "{dcmdLib}"DRuntime.o "{Libraries}"Interface.o -o Tracks
-
- # This will build the dcmd and copy it to your debugger prefs file or tmon file
- BuildDcmd Tracks 1322
-
- Echo 'include "Tracks";' | Rez -a -o "{systemFolder}TMON Folder:dcmd holder"
- Echo 'include "Tracks";' | Rez -a -o "{systemFolder}Debugger prefs"
-
- **********************************************************************/
-
- #include <Types.h>
- #include "dcmd.h"
- #include <Devices.h>
- #include <string.h>
- #include <Errors.h>
-
- #include "::Tracks.h" // Look one folder back for this file
- #include "Put.h"
-
- void PutSignedWord(short err);
- Boolean EqlStr(const char *a, const char *b);
- short GetDrvrRefNum(char *driverName);
-
- pascal void CommandEntry (dcmdBlock* paramPtr)
- {
- Ptr csParamPtr;
- short csCode,refNum;
- Str255 formatstring;
- short err;
- TraceStatusBlk status;
- TraceParamBlock param;
- char len, x;
- char *help0 = "\pTo be used with Tracks";
- char *help1 = "\pSyntax Error";
- char *help2 = "\pFormat: Tracks On .DrvrName | Off | Write | Info";
- char drvrName[255];
-
- switch (paramPtr->request)
- {
- case dcmdInit:
- break;
-
- case dcmdHelp:
- dcmdDrawLine (help0);
- dcmdDrawLine (help2);
- break;
-
- case dcmdDoIt:
- {
-
- dcmdSwapWorlds(); // We access machine state. (i think)
-
- (void)dcmdGetNextParameter(formatstring);
- // get the length byte and convert to uppercase
- len = *formatstring;
- for (x=1;x<len+1;x++)
- if (formatstring[x] <= 'z' && formatstring[x] >= 'a')
- formatstring[x] -= ('a'-'A');
- PutPStr("\pTracks ");
-
- PutLine();
- PutPStr(formatstring);
- PutLine();
-
- csParamPtr = nil;
- csCode = -1;
-
- // compare command with the pascal strings...
- if (EqlStr("ON", (char *)&formatstring[1]))
- {
- (void)dcmdGetNextParameter(formatstring);
- if (formatstring[1] == '.')
- {
- // it appears that TMON treats a period before a word as a separate word...
- // so I check for a single word consisting of a period here..
- if (formatstring[0] == 1)
- {
- // Must be using TMON... Grab the next word, and stuff
- // driver name into drvrName and put in period & new length byte.
-
- (void)dcmdGetNextParameter(formatstring);
- len = *formatstring;
- for (x=0;x<len+1;x++)
- drvrName[x+2] = formatstring[x+1];
- drvrName[0] = len+1;
- drvrName[1] = '.';
- } else
- {
- len = *formatstring;
- for (x=0;x<len+1;x++)
- drvrName[x] = formatstring[x];
- }
- // the next parameter needs to be the name of the driver to be traced
- // it'll return error if not there or the wrong name is specified.
- if (*drvrName != 0)
- {
- PutCStr("opening '");
- PutPStr(drvrName);
- PutCStr("'");
- PutLine();
- csCode = kSetTraceOnline;
- csParamPtr = (Ptr)drvrName;
- }
-
- } else PutCStr("missing period");
- }
- else
- if (EqlStr("OFF", (char *)&formatstring[1]))
- {
- csCode = kSetTraceOffline;
- }
- else
- if (EqlStr("WRITE", (char *)&formatstring[1]))
- {
- csCode = kWriteTraceBuffer;
- }
- else
- if (EqlStr("INFO", (char *)&formatstring[1]) || (*formatstring == 0))
- {
- param.u.getStatus.statusPtr = &status;
- csCode = kGetTraceStatus;
- csParamPtr = (Ptr) ¶m;
- }
-
- if (csCode != -1)
- {
- // err = OpenDriver ("\p.TRACE", &refNum);
- // the following line is better than using OpenDriver since it doesnt move mem.
-
- refNum = GetDrvrRefNum((char *)"\p.TRACE");
-
-
- if (refNum != 0)
- err = Control(refNum, csCode, csParamPtr);
- else
- {
- err = dInstErr;
- PutCStr("Couldnt open Tracks.");
- }
-
- if ((err == noErr) && (csCode == kGetTraceStatus))
- {
- PutCStr(" Tracks :");
- if (status.online) PutCStr(" On");
- else PutCStr(" Off");
- PutLine();
-
- PutCStr(" Periodic write to file:");
- if (status.autoWrite) PutCStr(" On");else PutCStr(" Off");
- PutLine();
-
-
- PutCStr(" bufferSize: ");
- PutUDec(status.bufferSize);
- if (status.bufferSize == 0) PutCStr(" (Tracks not available)");
- PutLine();
-
- PutCStr(" bytesBuffered: "); PutUDec(status.bytesBuffered);PutLine();
- PutCStr(" File Length: "); PutUDec(status.bytesWritten);PutLine();
- dcmdDrawLine (help2);
- }
- else
- {
- PutCStr("Result: ");
- PutSignedWord(err);
- if (err == aspBufTooSmall) PutCStr("(Buffer too small)");
- PutLine();
- }
- }
- else // no match of parameter...
- {
- dcmdDrawLine (help0);
- dcmdDrawLine (help2);
- }
- dcmdSwapWorlds(); // undo
- }
- break;
- }
- } // CommandEntry
-
-
- // displays a signed value using Put's unsigned short printer.
- void PutSignedWord(short err)
- {
- if (err & 0x8000) // it's negitive
- {
- err = 0xFFFF - err;
- err++;
- PutChar('-');
- }
- PutUDec((long)err);
- }
-
- Boolean EqlStr(const char *a, const char *b)
- {
- while (*a)
- if (*a++ != *b++) return false;
- return true;
- }
- // This was taken from tech note 171
- // (modified slightly)
- short GetDrvrRefNum(char *driverName)
- { /* GetDrvrRefNum */
-
- #define UnitNtryCnt 0x1d2
-
- /*bit in dCtlFlags that indicates ROM/RAM*/
- #define dRAMBased 6
- /*length byte and name of driver [string]*/
- #define drvrName 0x12
-
- short negCount,dRef;
- DCtlHandle DCEH;
- char *drivePtr,*s;
- Boolean found;
-
- negCount = -*(short *)(UnitNtryCnt); /*get -(table size)*/
-
- /*Check to see that driver is installed, obtain refNum.*/
- /*Assumes that an Open was done previously -- probably by an INIT.*/
- /*Driver doesn't have to be open now, though.*/
-
-
- dRef = -12 + 1; /*we'll start with driver refnum == -12,
- right after .ATP entry*/
-
- /*Look through unit table until we find the driver or reach the end.*/
-
- do
- {
- dRef -= 1; /*bump to next refnum*/
- DCEH = GetDCtlEntry(dRef); /*get handle to DCE*/
-
- s = "";
-
- if ((DCEH != nil) && ( (**DCEH).dCtlDriver != nil) )
- {
- if (((**DCEH).dCtlFlags >> dRAMBased) & 1)
- /* test dRamBased bit */
- drivePtr = *(Handle) (**DCEH).dCtlDriver;
- /*zee deréference*/
- else
- drivePtr = (**DCEH).dCtlDriver;
-
- if (drivePtr != nil)
- s = drivePtr + drvrName;
- }
-
- found = EqualString(s,driverName,0,0);
-
-
- } while (!found && (dRef != negCount));
- /*Loop until we find it or we've just looked at the last slot.*/
-
- return found ? dRef : 0; // if found return dRef, else 0
-
- }/* GetDrvrRefNum */
-
-
- // This is so we don't have to include StdCLib.o -
- size_t strlen (const char *s)
- {
- register size_t size = 0;
- while (*s++) size++;
- return size;
-
- }
-